﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Aioms.Common;
using Aioms.Model;
using Aioms.Models;
using Furion.DynamicApiController;
using Furion.UnifyResult;
using Masuit.Tools;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Models;
using Newtonsoft.Json.Linq;
using SqlSugar;

namespace Aioms.Controllers
{
    /// <summary>
    /// 定时任务类
    /// </summary>
    [DynamicApiController]
    public class CronController
    {
        private readonly ISqlSugarClient db; // 核心对象：拥有完整的SqlSugar全部功能
        public CronController(ISqlSugarClient sqlSugarClient)
        {
            this.db = sqlSugarClient;
        }

        /// <summary>
        /// 根据数据库表生成所有Model
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> GetGeneratetpworkorder() {
            Console.WriteLine($"{DateTime.Now} 计划任务开始执行");
            // 如果当前任务计划执行过，将不再执行
            Croninfo croninfo = await db.Queryable<Croninfo>().Where(c => c.Leixing == "计划" && c.Created.Date == DateTime.Now.Date).SingleAsync();
            if (croninfo == null)
            {
                String format_current_date = DateTime.Now.ToString("yyyy-MM-dd");

                int day_of_week = Convert.ToInt32(DateTime.Now.DayOfWeek); // 本周几
                int day_of_month = Convert.ToInt32(DateTime.Now.Day);

                #region 临时计划
                /*
                List<TaskPlan> temp_taskPlanList = await db.Queryable<TaskPlan>().Where(tp => tp.IsDel == 0).Where(tp => tp.Period == "临时").Where(tp => tp.Status == "ok").ToListAsync();
                if (temp_taskPlanList?.Count > 0)
                {
                    foreach (var ttp in temp_taskPlanList)
                    {
                        String js_temp_date = ttp.BeginDate.ToString("yyyy-MM-dd");
                        if (js_temp_date.Equals(format_current_date))
                        {
                            Object ti = new();
                            if (ttp.Type.Equals("巡检计划"))
                            {
                                ti = GetXunJianData(ttp.RefIds.ToInt32()).Result;
                            }
                            else if (ttp.Type.Equals("点检计划"))
                            {
                                ti = GetDianJianData(ttp.RefIds).Result;
                            }
                            else if (ttp.Type.Equals("保养计划"))
                            {
                                ti = GetBaoYangData(ttp.RefIds).Result;
                            }
                            else
                            {

                            }
                            // 发送到工单数据库
                            await db.Insertable<TpWorkOrder>(new TpWorkOrder { Eid = ttp.Eid, Number = DateTime.Now.ToString("yyyyMMddHHmmss"), Source = "计划", RefId = ttp.Id, Name = ttp.Name, Type = ttp.Type.Replace("计划", "工单"), Extra = ttp.Period, BeginTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " " + ttp.BeginTime), EndTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " " + ttp.EndTime), ManHour = ttp.ManHour, SjBeginTime = DateTime.MinValue, SjEndTime = DateTime.MinValue, SjManHour = 0, Epids = ttp.Epids, Imageurl = "", Videourl = "", Voiceurl = "", Status = "未开始", Progress = "", TaskInfo = ti }).ExecuteCommandAsync();
                        }
                    }
                }
                Console.WriteLine("临时计划执行结束！！！");*/
                #endregion

                #region 周计划
                // 周计划
                List<TaskPlan> week_taskPlanList = await db.Queryable<TaskPlan>().Where(tp => tp.IsDel == 0).Where(tp => tp.Period == "周").Where($"FIND_IN_SET({day_of_week}, period_day)").Where(tp => tp.Status == "ok").ToListAsync();
                if (week_taskPlanList?.Count > 0)
                {
                    foreach (var wtp in week_taskPlanList)
                    {
                        JObject ti = new();
                        if (wtp.Type.Equals("巡检计划"))
                        {
                            ti = JObject.FromObject(GetXunJianData(wtp.RefIds.ToInt32()).Result);
                        }
                        else if (wtp.Type.Equals("点检计划"))
                        {
                            ti = JObject.FromObject(GetDianJianData(wtp.RefIds).Result);
                        }
                        else if (wtp.Type.Equals("保养计划"))
                        {
                            ti = JObject.FromObject(GetBaoYangData(wtp.RefIds).Result);
                        }
                        else { }
                        // 发送到工单数据库
                        await db.Insertable<TpWorkOrder>(new TpWorkOrder { Eid = wtp.Eid, Number = DateTime.Now.ToString("yyyyMMddHHmmss") + wtp.Id, Source = wtp.Source, RefId = wtp.Id, Name = wtp.Name, Type = wtp.Type.Replace("计划", "工单"), Extra = wtp.Period, BeginTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " " + wtp.BeginTime), EndTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " " + wtp.EndTime), ManHour = wtp.ManHour, SjBeginTime = DateTime.MinValue, SjEndTime = DateTime.MinValue, SjManHour = 0, Epids = wtp.Epids, Imageurl = "", Videourl = "", Voiceurl = "", Status = "未开始", Progress = "", SjWxEpId = 0, SjWxEpRealname = "", TaskInfo = ti }).ExecuteCommandAsync();
                    }
                }
                Console.WriteLine("周计划执行结束！！！");
                #endregion

                #region 月计划
                // 月计划
                List<TaskPlan> month_taskPlanList = await db.Queryable<TaskPlan>().Where(tp => tp.IsDel == 0).Where(tp => tp.Period == "月").Where($"FIND_IN_SET({day_of_month}, period_day)").Where(tp => tp.Status == "ok").ToListAsync();
                if (month_taskPlanList.Count > 0)
                {
                    foreach (var mtp in month_taskPlanList)
                    {
                        JObject ti = new();
                        if (mtp.Type.Equals("巡检计划"))
                        {
                            ti = JObject.FromObject(GetXunJianData(mtp.RefIds.ToInt32()).Result);
                        }
                        else if (mtp.Type.Equals("点检计划"))
                        {
                            ti = JObject.FromObject(GetDianJianData(mtp.RefIds).Result);
                        }
                        else if (mtp.Type.Equals("保养计划"))
                        {
                            ti = JObject.FromObject(GetBaoYangData(mtp.RefIds).Result);
                        }
                        else { }
                        // 发送到工单数据库
                        await db.Insertable<TpWorkOrder>(new TpWorkOrder { Eid = mtp.Eid, Number = DateTime.Now.ToString("yyyyMMddHHmmss") + mtp.Id, Source = mtp.Source, RefId = mtp.Id, Name = mtp.Name, Type = mtp.Type.Replace("计划", "工单"), Extra = mtp.Period, BeginTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " " + mtp.BeginTime), EndTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " " + mtp.EndTime), ManHour = mtp.ManHour, SjBeginTime = DateTime.MinValue, SjEndTime = DateTime.MinValue, SjManHour = 0, Epids = mtp.Epids, Imageurl = "", Videourl = "", Voiceurl = "", Status = "未开始", SjWxEpId = 0, SjWxEpRealname = "", Progress = "", TaskInfo = ti }).ExecuteCommandAsync();
                    }
                }
                Console.WriteLine("月计划执行结束！！！");
                #endregion

                #region 年计划
                // 年计划
                List<TaskPlan> year_taskPlanList = await db.Queryable<TaskPlan>().Where(tp => tp.IsDel == 0).Where(tp => tp.Period == "年").Where(tp => tp.Status == "ok").ToListAsync();
                if (year_taskPlanList?.Count > 0)
                {
                    foreach (var ytp in year_taskPlanList)
                    {
                        // 计算出来年计划多少天后的日期
                        DateTime js_year_date = ytp.BeginDate.AddDays(Convert.ToInt32(ytp.PeriodDay));
                        String format_js_date = js_year_date.ToString("yyyy-MM-dd");

                        // 跟当前时间作比较，看是否是当天
                        if (format_current_date.Equals(format_js_date))
                        {
                            JObject ti = new();
                            if (ytp.Type.Equals("巡检计划"))
                            {
                                ti = JObject.FromObject(GetXunJianData(ytp.RefIds.ToInt32()).Result);
                            }
                            else if (ytp.Type.Equals("点检计划"))
                            {
                                ti = JObject.FromObject(GetDianJianData(ytp.RefIds).Result);
                            }
                            else if (ytp.Type.Equals("保养计划"))
                            {
                                ti = JObject.FromObject(GetBaoYangData(ytp.RefIds).Result);
                            }
                            else { }
                            // 发送到工单数据库
                            await db.Insertable<TpWorkOrder>(new TpWorkOrder { Eid = ytp.Eid, Number = DateTime.Now.ToString("yyyyMMddHHmmss") + ytp.Id, Source = ytp.Source, RefId = ytp.Id, Name = ytp.Name, Type = ytp.Type.Replace("计划", "工单"), Extra = ytp.Period, BeginTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " " + ytp.BeginTime), EndTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " " + ytp.EndTime), ManHour = ytp.ManHour, SjBeginTime = DateTime.MinValue, SjEndTime = DateTime.MinValue, SjManHour = 0, Epids = ytp.Epids, Imageurl = "", Videourl = "", Voiceurl = "", Status = "未开始", SjWxEpId = 0, SjWxEpRealname = "", Progress = "", TaskInfo = ti }).ExecuteCommandAsync();
                        }
                    }
                }
                Console.WriteLine("年计划执行结束！！！");
                #endregion

                await db.Insertable<Croninfo>(new Croninfo { Leixing = "计划" }).ExecuteCommandAsync();
            }
            return new JsonResult(new RESTfulResult<object>
            {
                StatusCode = 200,
                Succeeded = true,
                Data = "生成计划任务成功",
                Errors = null,
                Extras = UnifyContext.Take(),
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            });
        }

        [NonAction]
        public async Task<XunJianPlan> GetXunJianData(long id)
        {
            XunJianPlan xjp = new();

            // 第一步：查找巡检路线
            InspectionLine il = await db.Queryable<InspectionLine>().InSingleAsync(id);
            if (il != null)
            {
                xjp.Id = il.Id;
                xjp.Eid = il.Eid;
                xjp.Name = il.Name;
                xjp.IsDel = il.IsDel;
                // 第二步：查找巡检点
                List<InspectionPoint> ips = await db.Queryable<InspectionPoint>().Where(ip => ip.Ilid == il.Id && ip.IsDel == 0).ToListAsync();
                foreach (var ip in ips)
                {
                    XunJianDian xjd = new();
                    xjd.Id = ip.Id;
                    xjd.Eid = ip.Eid;
                    xjd.Name = ip.Name;
                    xjd.Position = ip.Position;
                    xjd.Range = ip.Range;
                    xjd.IsDel = ip.IsDel;
                    // 第三步：查找巡检点巡检项
                    List<InspectionOption> ios = await db.Queryable<InspectionOption>().Where(io => io.Ipid == ip.Id).ToListAsync();
                    foreach (var io in ios)
                    {
                        XunJianDianXunJianXiang xjdxjx = new();
                        xjdxjx.Id = io.Id;
                        xjdxjx.Eid = io.Eid;
                        xjdxjx.Procedure = io.Procedure;
                        xjdxjx.Record = io.Record;
                        xjdxjx.Option = io.Option;
                        xjdxjx.ImageUrl = io.Image;
                        xjdxjx.VideoUrl = io.Video;

                        xjd.XunJianXiangs.Add(xjdxjx);
                    }
                    // 第四步：查找设备
                    if (!string.IsNullOrEmpty(ip.Dvids)) {
                        List<Device> devices = await db.Queryable<Device>().Where($"json_contains('{ip.Dvids}', json_array(id))").ToListAsync();
                        foreach (var device in devices)
                        {
                            XunJianDevice xjdv = new();
                            xjdv.Id = device.Id;
                            xjdv.Eid = device.Eid;
                            xjdv.Name = device.Name;
                            xjdv.AeName = device.Aename;
                            xjdv.Position = device.Position;
                            xjdv.IsDel = device.IsDel;
                            xjdv.Number = device.Number;
                            xjdv.Specification = device.Specification;
                            xjdv.AeId = device.Aeid;
                            xjdv.DvtId = device.Dvtid;
                            xjdv.DvtName = device.Dvtname;

                            // 第五步：根据设备类型查找巡检项
                            List<InspectionStandard> istds = await db.Queryable<InspectionStandard>().Where(istd => istd.Dvtid == device.Dvtid).ToListAsync();
                            foreach (var istd in istds)
                            {
                                DeviceXunJianStandard dxjs = new();
                                dxjs.Id = istd.Id;
                                dxjs.Eid = istd.Eid;
                                dxjs.Procedure = istd.Procedure;
                                dxjs.Record = istd.Record;
                                dxjs.Option = istd.Option;
                                dxjs.ImageUrl = istd.ImgUrl;
                                dxjs.VideoUrl = istd.VideoUrl;

                                xjdv.DeviceXunJianStandards.Add(dxjs);
                            }

                            xjd.XunJianDevices.Add(xjdv);
                        }
                    }
                    
                    xjp.XunJianDians.Add(xjd);
                }
            }
            return xjp;
        }

        [NonAction]
        public async Task<DianJianPlan> GetDianJianData(string dvids)
        {
            DianJianPlan djp = new();

            // 第一步：查找设备
            List<Device> devices = await db.Queryable<Device>().Where($"FIND_IN_SET(id, '{dvids}')").ToListAsync();
            foreach (var device in devices)
            {
                DianJianDevice djdv = new();
                djdv.Id = device.Id;
                djdv.Eid = device.Eid;
                djdv.Name = device.Name;
                djdv.AeName = device.Aename;
                djdv.Position = device.Position;
                djdv.IsDel = device.IsDel;
                djdv.Number = device.Number;
                djdv.Specification = device.Specification;
                djdv.AeId = device.Aeid;
                djdv.DvtId = device.Dvtid;
                djdv.DvtName = device.Dvtname;

                // 第二步：根据设备类型查找巡检项
                List<PointInspectionStandard> pistds = await db.Queryable<PointInspectionStandard>().Where(pistd => pistd.Dvtid == device.Dvtid).ToListAsync();
                foreach (var pistd in pistds)
                {
                    DeviceDianJianStandard ddjs = new();
                    ddjs.Id = pistd.Id;
                    ddjs.Eid = pistd.Eid;
                    ddjs.Standard = pistd.Standard;
                    ddjs.Record = pistd.Record;
                    ddjs.Option = pistd.Option;
                    ddjs.Position = pistd.Position;
                    ddjs.ImageUrl = pistd.ImgUrl;
                    ddjs.VideoUrl = pistd.VideoUrl;

                    djdv.DeviceDianJianStandards.Add(ddjs);
                }

                djp.DianJianDevices.Add(djdv);
            }
            return djp;
        }

        [NonAction]
        public async Task<BaoYangPlan> GetBaoYangData(string dvids)
        {
            BaoYangPlan byp = new();

            // 第一步：查找设备
            List<Device> devices = await db.Queryable<Device>().Where($"FIND_IN_SET(id, '{dvids}')").ToListAsync();
            foreach (var device in devices)
            {
                BaoYangDevice bydv = new();
                bydv.Id = device.Id;
                bydv.Eid = device.Eid;
                bydv.Name = device.Name;
                bydv.AeName = device.Aename;
                bydv.Position = device.Position;
                bydv.IsDel = device.IsDel;
                bydv.Number = device.Number;
                bydv.Specification = device.Specification;
                bydv.AeId = device.Aeid;
                bydv.DvtId = device.Dvtid;
                bydv.DvtName = device.Dvtname;

                // 第二步：根据设备类型查找巡检项
                List<MaintenanceStandard> pistds = await db.Queryable<MaintenanceStandard>().Where(pistd => pistd.Dvtid == device.Dvtid).ToListAsync();
                foreach (var pistd in pistds)
                {
                    DeviceBaoYangStandard dbys = new();
                    dbys.Id = pistd.Id;
                    dbys.Eid = pistd.Eid;
                    dbys.Standard = pistd.Standard;
                    dbys.Position = pistd.Position;
                    dbys.ImageUrl = pistd.ImgUrl;
                    dbys.VideoUrl = pistd.VideoUrl;

                    bydv.DeviceBaoYangStandards.Add(dbys);
                }

                byp.BaoYangDevices.Add(bydv);
            }
            return byp;
        }
    }
}
